#pragma once
#include <string>
#include <mysql/mysql.h>
#include <memory>
#include <ctime>
#include "Log.hpp"
class Connection
{
public:
    using ptr = std::shared_ptr<Connection>;
    // 初始化数据库连接
    Connection()
    {
        // 初始化
        _conn = mysql_init(nullptr);
        if (_conn == nullptr)
        {
            LOG(ERROR, "初始化句柄失败！原因:%s\n", mysql_error(_conn));
            return;
        }
    }
    // 释放数据库连接资源
    ~Connection()
    {
        if (_conn)
        {
            mysql_close(_conn);
            LOG(INFO, "句柄释放成功!\n");
        }
    }
    // 连接数据库
    bool connect(const std::string &ip,
                 unsigned int port,
                 const std::string &username,
                 const std::string &password,
                 const std::string &dbname)
    {
        // 连接数据库
        MYSQL *res = mysql_real_connect(_conn,
                                    ip.c_str(), 
                                    username.c_str(),password.c_str(), 
                                    dbname.c_str(), port, nullptr, 0);
        return res != nullptr;
    }
    // 更新或者新增
    bool update(const std::string &sql)
    {
        if (mysql_query(_conn, sql.c_str()))
        {
            LOG(ERROR,"更新失败:%s\n",sql.c_str());
            return false;
        }
	    return true;
    }
    // 查询操作 select--返回结果集
    std::shared_ptr<MYSQL_RES> query(const std::string &sql)
    {
        if (mysql_query(_conn, sql.c_str()))
        {
            LOG(ERROR,"查询失败:%s\n",sql.c_str());
            return nullptr;
        }
        //记得外部释放！
        std::shared_ptr<MYSQL_RES> res(mysql_store_result(_conn),[&](MYSQL_RES* res)
        {
            if(res)
            {
                std::cout<<"释放结果集\n";
                mysql_free_result(res);
            }
        });
        return res;
    }

    // 刷新一下连接的起始的空闲时间点
    void refreshAliveTime() { _alivetime = time(nullptr); }
    // 返回存活的时间
    time_t getAliveeTime() const { return time(nullptr) - _alivetime; }

private:
    MYSQL *_conn;      // 表示和MySQL Server的一条连接
    time_t _alivetime; // 记录进入空闲状态后的起始存活时间
};